package main

import (
	"encoding/json"
	"net/http"

	"github.com/gin-gonic/gin"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

type Post struct {
	Id           uint      `json:"id"`
	Title        string    `json:"title"`
	Description  string    `json:"description"`
	Comments     []Comment `json:"comments" gorm:"-" default:"[]"` // gorm:"-" db.AutoMigrate不会创建该字段
	CommentsJson string    `json:"-"`                              // JSON上传数据时不需要该字段
}

type Comment struct {
	Text string `json:"text"`
}

func main() {
	db, err := gorm.Open(mysql.Open("root:root@tcp(127.0.0.1:3306)/go_posts"), &gorm.Config{})

	if err != nil {
		panic(err)
	}

	db.AutoMigrate(Post{})

	app := gin.Default()

	api := app.Group("/api")
	{
		api.GET("/posts", func(c *gin.Context) {
			var posts []Post
			db.Find(&posts)

			for i, post := range posts {

				var comments []Comment

				if err := json.Unmarshal([]byte(post.CommentsJson), &comments); err != nil {
					panic(err)
				}

				posts[i].Comments = comments
			}

			c.JSON(http.StatusOK, gin.H{"result": posts})
		})

		api.POST("/posts", func(c *gin.Context) {
			var post Post
			if err := c.ShouldBindJSON(&post); err != nil {
				panic(err)
			} else {
				// 第一次请求的时候，这里是必须的，否则第98行会出错
				post.CommentsJson = "[]"
				db.Create(&post)
				c.JSON(http.StatusCreated, gin.H{"result": post})
			}
		})

		api.POST("/posts/:id/comments", func(c *gin.Context) {
			var post Post

			id := c.Param("id")
			db.First(&post, "id = ?", id)

			var body map[string]string

			if err := c.ShouldBindJSON(&body); err != nil {
				panic(err)
			}

			var comments []Comment

			if err := json.Unmarshal([]byte(post.CommentsJson), &comments); err != nil {
				panic(err)
			}

			comments = append(comments, Comment{
				Text: body["text"],
			})

			commentsJson, err := json.Marshal(comments)

			if err != nil {
				panic(err)
			}

			db.Model(post).Where("id = ?", id).Update("comments_json", string(commentsJson))

			c.JSON(http.StatusOK, gin.H{"result": post})

		})
	}

	app.Run(":8000")
}
